﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using System;
using UnityEngine.UI;
using DG.Tweening;

public class Slot : MonoBehaviour, IPointerClickHandler
{
    public GameObject addScorePrefab;
    private Animator anim;
    private bool[] isFilled = new bool[6];

    [HideInInspector]
    public List<GameObject> slices = new List<GameObject>();
    public static bool isLocked = false;

    private void Start()
    {
        anim = GetComponent<Animator>();
    }

    public void OnPointerClick(PointerEventData eventData)
    {
        if (isLocked || MainController.instance.hasNoMove || MainController.instance.currentSlice == null) return;

        isLocked = true;
        Turn turn = MainController.instance.currentTurn;
        int angle = turn.angle;
        int isAdded = 0;

        if (turn.type == Slice.Type.Slice1)
        {
            if (!isFilled[angle])
            {
                isFilled[angle] = true;
                isAdded = 1;
            }
        }
        else if (turn.type == Slice.Type.Slice2)
        {
            if (!isFilled[angle] && !isFilled[angle + 1])
            {
                isFilled[angle] = true;
                isFilled[angle + 1] = true;
                isAdded = 2;
            }
        }
        else
        {
            if (!isFilled[angle] && !isFilled[angle + 1] && !isFilled[angle + 2])
            {
                isFilled[angle] = true;
                isFilled[angle + 1] = true;
                isFilled[angle + 2] = true;
                isAdded = 3;
            }
        }

        anim.SetTrigger("onClick");

        var currentSliceScript = MainController.instance.currentSlice;
        GameObject currentSlice = currentSliceScript.gameObject;
        Transform imageTr = transform.GetChild(0);

        if (isAdded > 0)
        {
            currentSlice.transform.DOMove(imageTr.position, 0.2f);

            Timer.Schedule(this, 0.2f, () =>
            {
                currentSlice.transform.SetParent(imageTr);
                slices.Add(currentSlice);
                MainController.instance.Score += isAdded;
                currentSliceScript.AddScoreEffect();
                isLocked = false;

                bool isExploded = CheckExplosion();
                if (isExploded)
                {
                    MainController.instance.HeavyVibration();
                    MainController.instance.PlayExplosion();
                }
                else
                {
                    MainController.instance.LightVibration();
                    MainController.instance.PlayAddToSlot();
                }

                MainController.instance.NextTurn();
            });
        }
        else
        {
            currentSlice.transform.DOMove(imageTr.position, 0.2f);
            Timer.Schedule(this, 0.2f, () =>
            {
                currentSlice.transform.position = MainController.instance.centerTr.position;
                currentSlice.transform.DORotate(currentSlice.transform.eulerAngles + new Vector3(0, 0, 360), 0.35f, RotateMode.LocalAxisAdd);
                Timer.Schedule(this, 0.35f, () =>
                {
                    isLocked = false;
                });
            });
        }
    }

    public bool HasMove(Turn turn)
    {
        int angle = turn.angle;
        return turn.type == Slice.Type.Slice1 && !isFilled[angle] ||
               turn.type == Slice.Type.Slice2 && !isFilled[angle] && !isFilled[angle + 1] ||
               turn.type == Slice.Type.Slice3 && !isFilled[angle] && !isFilled[angle + 1] && !isFilled[angle + 2];
    }

    public bool IsFull()
    {
        foreach(var filled in isFilled)
        {
            if (filled == false) return false;
        }
        return true;
    }

    private bool CheckExplosion()
    {
        if (IsFull())
        {
            var slots = MainController.instance.slots;
            int index = Array.IndexOf(slots, this);

            AddScoreEffect();
            slots[(index + 1) % 6].AddScoreEffect();
            slots[(index + 5) % 6].AddScoreEffect();

            Explode();
            slots[(index + 1) % 6].Explode();
            slots[(index + 5) % 6].Explode();

            return true;
        }
        return false;
    }

    public void Explode()
    {
        var imageTr = transform.GetChild(0);
        for(int i = 0; i < isFilled.Length; i++)
        {
            if (isFilled[i])
            {
                Vector3 position = imageTr.GetChild(i).position;
                var explosion = Instantiate(MainController.instance.sliceExplosion, position, Quaternion.identity);
                Destroy(explosion, 0.5f);
            }
        }

        Clear();
    }

    public void Clear()
    {
        isFilled = new bool[6];
        foreach (var slice in slices)
        {
            Destroy(slice);
        }
        slices.Clear();
    }

    public void AddScoreEffect()
    {
        int score = slices.Count;
        if (score > 0)
        {
            Timer.Schedule(this, 0.3f, () =>
            {
                var effect = Instantiate(addScorePrefab);
                effect.transform.SetParent(transform);
                effect.transform.localScale = Vector3.zero;
                effect.transform.position = transform.GetChild(0).position; ;
                effect.GetComponent<Text>().text = "+" + score;
                effect.GetComponent<Text>().fontSize = 100;
                Destroy(effect, 2);
            });
        }
    }

    public void SetData(List<SliceData> sliceDatas)
    {
        Transform imageTr = transform.GetChild(0);

        foreach (var sliceData in sliceDatas)
        {
            var angle = sliceData.angle;
            var slice = Instantiate(MainController.instance.slicePrefabs[(int)sliceData.type], imageTr.position, Quaternion.identity, imageTr);
            slice.ApplyAngle(angle);
            slice.SetSprite(MainController.instance.currentSliceSprite);
            slices.Add(slice.gameObject);

            if (sliceData.type == Slice.Type.Slice1)
            {
                isFilled[angle] = true;
            }
            else if (sliceData.type == Slice.Type.Slice2)
            {
                isFilled[angle] = true;
                isFilled[angle + 1] = true;
            }
            else
            {
                isFilled[angle] = true;
                isFilled[angle + 1] = true;
                isFilled[angle + 2] = true;
            }
        }
    }

    public void SetSliceSprite(Sprite sprite)
    {
        foreach(var slice in slices)
        {
            slice.GetComponent<Slice>().SetSprite(sprite);
        }
    }

    public void TEXT1()
    {
        int textNum = 1;
        if (textNum == 1)
        {
            textNum = 2;
        }
    }
    public void TEXT2()
    {
        int textNum = 1;
        if (textNum == 1)
        {
            textNum = 2;
        }
    }
    public void TEXT3()
    {
        int textNum = 1;
        if (textNum == 1)
        {
            textNum = 2;
        }
    }

    public void TEXT4()
    {
        int textNum = 1;
        if (textNum == 1)
        {
            textNum = 2;
        }
    }

    public void TEXT5()
    {
        int textNum = 1;
        if (textNum == 1)
        {
            textNum = 2;
        }
    }

    public void TEXT6()
    {
        int textNum = 1;
        if (textNum == 1)
        {
            textNum = 2;
        }
    }

    public void TEXT8()
    {
        int textNum = 1;
        if (textNum == 1)
        {
            textNum = 2;
        }
    }

    public void TEXT9()
    {
        int textNum = 1;
        if (textNum == 1)
        {
            textNum = 2;
        }
    }

    public void TEXT10()
    {
        int textNum = 1;
        if (textNum == 1)
        {
            textNum = 2;
        }
    }

    public void TEXT11()
    {
        int textNum = 1;
        if (textNum == 1)
        {
            textNum = 2;
        }
    }

    public void TEXT12()
    {
        int textNum = 1;
        if (textNum == 1)
        {
            textNum = 2;
        }
    }

    public void TEXT13()
    {
        int textNum = 1;
        if (textNum == 1)
        {
            textNum = 2;
        }
    }

    public void TEXT14()
    {
        int textNum = 1;
        if (textNum == 1)
        {
            textNum = 2;
        }
    }

    public void TEXT15()
    {
        int textNum = 1;
        if (textNum == 1)
        {
            textNum = 2;
        }
    }

    public void TEXT16()
    {
        int textNum = 1;
        if (textNum == 1)
        {
            textNum = 2;
        }
    }

    public void TEXT17()
    {
        int textNum = 1;
        if (textNum == 1)
        {
            textNum = 2;
        }
    }
}
